package com.xwltz.common.phone.algorithm;

import com.xwltz.common.phone.base.PhoneBase;
import com.xwltz.common.phone.base.IspEnum;
import com.xwltz.common.phone.base.PhoneModel;

import java.util.Arrays;
import java.util.Optional;

/**
 * @description AnotherBinarySearchAlgorithm
 * @information on version 1.0 be created by @xwltz at 2021/11/08 15:20
 */

@SuppressWarnings({"DuplicatedCode", "unused"})
public class AnotherBinarySearchAlgorithm extends PhoneBase {
	@Override
	public Optional<PhoneModel> getInfo(String phoneNumber) {
		if (checkInvalidPhoneNumber(phoneNumber)) return Optional.empty();
		int attributionIdentity = checkPhoneNumberIsNumber(phoneNumber);
		if (attributionIdentity == 0) return Optional.empty();

		int left = indicesStartOffset;
		int right = indicesEndOffset;
		int mid = (left + right) / 2;
		mid = alignPosition(mid);
		while (mid >= left && mid <= right) {
			if (mid == right) {
				return Optional.empty();
			}
			int compare = compare(mid, attributionIdentity, originalByteBuffer);
			if (compare == 0) {
				break;
			}
			if (mid == left) {
				return Optional.empty();
			}

			if (compare > 0) {
				int tempMid = (mid + left) / 2;
				tempMid = alignPosition(tempMid);
				right = mid;
				int remain = (tempMid - indicesStartOffset) % 9;
				if (tempMid - indicesStartOffset < 9) {
					mid = tempMid - remain;
					continue;
				}
				if (remain != 0) {
					mid = tempMid + 9 - remain;
				} else {
					mid = tempMid;
				}
			} else {
				int tempMid = (mid + right) / 2;
				tempMid = alignPosition(tempMid);
				left = mid;
				int remain = (tempMid - indicesStartOffset) % 9;
				if (tempMid - indicesStartOffset < 9) {
					mid = tempMid - remain;
					continue;
				}
				if (remain != 0) {
					mid = tempMid + 9 - remain;
				} else {
					mid = tempMid;
				}
			}
		}

		originalByteBuffer.position(mid);
		int prefix = originalByteBuffer.getInt();
		int infoStartIndex = originalByteBuffer.getInt();
		byte ispMark = originalByteBuffer.get();
		IspEnum isp = IspEnum.of(ispMark).orElse(IspEnum.UNKNOWN);
		originalByteBuffer.position(infoStartIndex);
		int resultBufferSize = 200;
		int increase = 100;
		byte[] bytes = new byte[resultBufferSize];
		byte b;
		int i;
		for (i = 0; (b = originalByteBuffer.get()) != 0; i++) {
			bytes[i] = b;
			if (i == resultBufferSize - 1) {
				resultBufferSize = resultBufferSize + increase;
				bytes = Arrays.copyOf(bytes, resultBufferSize);
			}
		}
		String oriString = new String(bytes, 0, i);
		PhoneModel model = parse(phoneNumber, oriString, isp);
		return Optional.of(model);
	}
}
